/*
gobanjs - html5 SGF viewer for the Game of Go 

Copyright (C) 2013  Daniel Cioata
Visit http://www.govortex.ro/ for documentation, updates and examples.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/    

"use strict";

Node.prototype.addInfo=function(nodeInfo)
{
    this.info=nodeInfo;    
    this.children=null;
}

Node.prototype.addChild=function(node)
{
    if(this.children==null)
        this.children=new Array();
    node.parent=this;
    this.children.push(node);
}

Node.prototype.getStone=function()
{
    if(this.info!=null)
        return this.info.stone;
    return null;
}

Node.prototype.getChild=function(index)
{
    if((this.children!=null) && (this.children.length > index))
        return this.children[index];
    return null;
}

Node.prototype.getNumberOfChildren=function()
{
    if(this.children==null)
        return 0;
    return this.children.length;
}

NodeInfo.prototype.addInfo=function(p_id,p_info,gameTree)
{    
    var p,stone;    
    
    switch(p_id)
    {
        case SGFProp.ID_SZ:
		case SGFProp.ID_PW:
		case SGFProp.ID_PB:
		case SGFProp.ID_WR:
		case SGFProp.ID_BR:
		case SGFProp.ID_EV:
		case SGFProp.ID_DT:
		case SGFProp.ID_KM:
		case SGFProp.ID_RE:
		case SGFProp.ID_PL:
		case SGFProp.ID_C:			                  
             p=new Prop();
             p.id=p_id;
             p.label=p_info;
             if(p.id==SGFProp.ID_C)
                this.C=p_info;             
             else if(p.id==SGFProp.ID_SZ)
                gameTree.gameinfo.boardsize=parseInt(p_info);             
             else 
             {
                if(this.prop==null)
                    this.prop=new Array();
                this.prop.push(p);		                     
             }	               
             break;
        case SGFProp.ID_B:
        case SGFProp.ID_W:
        case SGFProp.ID_AW:
        case SGFProp.ID_AB:
            stone=new Stone();
            stone.x=p_info.charCodeAt(0)-97;
            stone.y=p_info.charCodeAt(1)-97;
            gameTree.computeBounds(stone.x,stone.y);
            if((p_id==SGFProp.ID_B) || (p_id==SGFProp.ID_AB))
            {
                stone.color=SGFProp.ID_B;
                if(p_id==SGFProp.ID_AB)
                    this.AB.push(stone);
                else
                    this.stone=stone;                            
            }
            else if((p_id==SGFProp.ID_W) || (p_id==SGFProp.ID_AW))
            {
                stone.color=SGFProp.ID_W;
                if(p_id==SGFProp.ID_AW)                    
                    this.AW.push(stone);
                else
                    this.stone=stone;                      
            }
            break;
        case SGFProp.ID_LB:
        case SGFProp.ID_TR:
        case SGFProp.ID_SQ:                                      
            p=new Prop();
            p.m_id=p_id;
            p.m_x=p_info.charCodeAt(0)-97;
            p.m_y=p_info.charCodeAt(1)-97;
            gameTree.computeBounds(stone.x,stone.y);                           
            if(p_id==SGFProp.ID_LB)
                p.label=p_info.toUpperCase().substr(3);
            if(this.markup==null)
            {
                this.markup=new Array();
            }
            this.markup.push(p);
            break;                                                 
    }     
}


GameTree.prototype.computeBounds=function(x,y)
{
    
   if(this.bounds.left > x)
        this.bounds.left=x;

   if(this.bounds.right < x)
        this.bounds.right = x;

   if(this.bounds.top > y)
        this.bounds.top=y;

   if(this.bounds.bottom < y)
        this.bounds.bottom = y;
}

GameTree.prototype.addNode=function(nodeInfo)
{    
    var node=new Node();
    node.addInfo(nodeInfo);
    
    if(this.root==null)
    {
        this.root=node;
        this.current=this.root;
    }
    else
    {
        if(this.current==null)
        {
            console.error("SGoGameTree: Invalid structure");
            return;
        }
        if(this.current.next==null)
        {
            this.current.next=node;
            node.prev=this.current;
            this.current=node;
        }
        else
        {
           this.current.addChild(node);
           this.current=node;
        }
    }
}

GameTree.prototype.pushCurrent=function()
{
    this.lstack.push(this.current);
}

GameTree.prototype.popCurrent=function()
{
    this.current=this.lstack.pop();
}

GameTree.prototype.traverse=function(root,control)
{
    var i;
    if(control<1000 && root!=null)
    {                            
        console.log(root.info);
        this.traverse(root.next,control++);        
        if(root.children!=null)
        {            
            for(i=0;i<root.children.length;i++)
               this.traverse(root.children[i],control++);          
        }                   
    }
}

GameTree.prototype.goRoot=function()
{
    this.current=this.root;
}

GameTree.prototype.moveNext=function()
{
    if((this.current!=null) && (this.current.next!=null))
    {
        this.current=this.current.next;
        return true;
    }
    return false;
}

GameTree.prototype.movePrev=function()
{
    if(this.current!=null)
    {
        if(this.current.prev!=null)
        {
            this.current=this.current.prev;
            return true;
        }
        else
        {
            if(this.current.parent!=null)
            {
                this.current=this.current.parent;
                return true;
            }
            
        }
    }
    return false;
}

GameTree.prototype.moveChild=function(ind)
{
    var cnr;
    if(this.current!=null)
    {
        cnr=this.current.getNumberOfChildren();
        if(cnr > ind)
        {
            this.current=this.current.children[ind];
            return true;
        }  
        else
        {
            console.log("invalid variation number");
        }  
    }
    return false;
}

GameTree.prototype.getCurrent=function()
{
    return this.current;
}

GameTree.prototype.getCurrentInfo=function()
{
    return this.current.info;
}

